package inabit.compiler.compiler;

import inabit.compiler.lexical.LexicalAnalyzer;
import inabit.compiler.parser.Parser;

import java.io.File;
import java.util.List;

/**Compiler of the rule definition file*/
/**@author Rafael Rocha*/
public abstract class LanguageCompiler<L extends LexicalAnalyzer, P extends Parser<?>> {
	private L lexer;
	private P parser;
	private boolean success;
	private long compileTimeMilliSeconds;
	private List<String> errorMessages;
	
	public LanguageCompiler(L lexer, P parser) {
		this.lexer = lexer;
		this.parser = parser;
		parser.setLexicalAnalyzer(lexer);
	}
	
	public boolean compileFromText(String text) throws Exception{
		init(lexer, parser);
		long start = System.currentTimeMillis();
		try {
			lexer.loadFromText(text);
		}catch(Exception e) {
			e.printStackTrace();
			return false;
		}
		success = parser.analyze();
		long end = System.currentTimeMillis();
		compileTimeMilliSeconds = end - start;
		deinit(lexer,parser);
		return success;
	}
	
	/**Compiles the specified file containing the rule definition
	 * returns <i>true</i> if the file was compiled successfully or false
	 * otherwise
	 * @throws Exception */
	public boolean compileFromFile(File file) throws Exception  {
		init(lexer, parser);
		long start = System.currentTimeMillis();
		try {
			lexer.loadFromFile(file);
		}catch(Exception e) {
			e.printStackTrace();
			return false;
		}
		success = parser.analyze();
		long end = System.currentTimeMillis();
		compileTimeMilliSeconds = end - start;
		deinit(lexer, parser);
		return success;
	}
	public List<String> getErrorMessages() {
		return errorMessages;
	}
	/**Returns the time that it took to read and compile the
	 *rule definition file in milliseconds*/
	public long getCompileTime() {
		return compileTimeMilliSeconds;
	}
	protected abstract void init(L lexer, P parser);
	protected abstract void deinit(L lexer, P parser);
}
